#include "gtklistitemmanagerprivate.h"
+#include "gtkwidgetprivate.h"
+
struct _GtkListItemManager
{
GObject parent_instance;
return GTK_WIDGET (result);
}
+/**
+ * gtk_list_item_manager_move_list_item:
+ * @self: a #GtkListItemManager
+ * @list_item: an acquired #GtkListItem that should be moved to represent
+ * a different row
+ * @position: the new position of that list item
+ * @prev_sibling: the new previous sibling
+ *
+ * Moves the widget to represent a new position in the listmodel without
+ * releasing the item.
+ *
+ * This is most useful when scrolling.
+ **/
+void
+gtk_list_item_manager_move_list_item (GtkListItemManager *self,
+ GtkWidget *list_item,
+ guint position,
+ GtkWidget *prev_sibling)
+{
+ gpointer item;
+
+ item = g_list_model_get_item (self->model, position);
+ gtk_list_item_factory_bind (self->factory, GTK_LIST_ITEM (list_item), position, item);
+ gtk_widget_insert_after (list_item, _gtk_widget_get_parent (list_item), prev_sibling);
+ g_object_unref (item);
+}
+
/**
* gtk_list_item_manager_update_list_item:
* @self: a #GtkListItemManager
}
static void
-gtk_list_view_release_rows (GtkListView *self)
+gtk_list_view_release_rows (GtkListView *self,
+ GQueue *released)
{
ListRow *row, *prev, *next;
guint i;
{
if (row->widget)
{
- gtk_list_item_manager_release_list_item (self->item_manager, NULL, row->widget);
+ g_queue_push_tail (released, row->widget);
row->widget = NULL;
i++;
prev = gtk_rb_tree_node_get_previous (row);
if (row->widget)
{
- gtk_list_item_manager_release_list_item (self->item_manager, NULL, row->widget);
+ g_queue_push_tail (released, row->widget);
row->widget = NULL;
prev = gtk_rb_tree_node_get_previous (row);
if (prev && gtk_list_view_merge_list_rows (self, prev, row))
{
if (next->widget)
{
- gtk_list_item_manager_release_list_item (self->item_manager, NULL, next->widget);
+ g_queue_push_tail (released, next->widget);
next->widget = NULL;
}
gtk_list_view_merge_list_rows (self, row, next);
{
ListRow *row, *new_row;
guint i, offset;
- GtkWidget *insert_after;
+ GtkWidget *widget, *insert_after;
+ GQueue released = G_QUEUE_INIT;
- gtk_list_view_release_rows (self);
+ gtk_list_view_release_rows (self, &released);
row = gtk_list_view_get_row (self, self->anchor_start, &offset);
if (offset > 0)
}
if (new_row->widget == NULL)
{
- new_row->widget = gtk_list_item_manager_acquire_list_item (self->item_manager,
- i,
- insert_after);
+ new_row->widget = g_queue_pop_head (&released);
+ if (new_row->widget)
+ {
+ gtk_list_item_manager_move_list_item (self->item_manager,
+ new_row->widget,
+ i,
+ insert_after);
+ }
+ else
+ {
+ new_row->widget = gtk_list_item_manager_acquire_list_item (self->item_manager,
+ i,
+ insert_after);
+ }
}
}
else
}
insert_after = new_row->widget;
}
+
+ while ((widget = g_queue_pop_head (&released)))
+ gtk_list_item_manager_release_list_item (self->item_manager, NULL, widget);
}
static void